home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / manageme / tcpdump-.001 / tcpdump-~ / tcpdump-3.0.2-linux / tcpdump-3.0.2 / print-tcp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-16  |  6.6 KB  |  277 lines

  1. /*
  2.  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21.  
  22. #ifndef lint
  23. static char rcsid[] =
  24.     "@(#) $Header: print-tcp.c,v 1.28 94/06/16 01:26:40 mccanne Exp $ (LBL)";
  25. #endif
  26.  
  27. #include <sys/param.h>
  28. #include <sys/time.h>
  29. #include <sys/types.h>
  30.  
  31. #include <netinet/in.h>
  32. #include <netinet/in_systm.h>
  33. #include <netinet/ip.h>
  34. #include <netinet/ip_var.h>
  35. #include <netinet/tcp.h>
  36. #include <netinet/tcpip.h>
  37.  
  38. #include <stdio.h>
  39. #ifdef __STDC__
  40. #include <stdlib.h>
  41. #endif
  42. #include <unistd.h>
  43.  
  44. #include "interface.h"
  45. #include "addrtoname.h"
  46.  
  47. #ifndef TCPOPT_WSCALE
  48. #define    TCPOPT_WSCALE        3    /* window scale factor (rfc1072) */
  49. #endif
  50. #ifndef TCPOPT_SACKOK
  51. #define    TCPOPT_SACKOK        4    /* selective ack ok (rfc1072) */
  52. #endif
  53. #ifndef TCPOPT_SACK
  54. #define    TCPOPT_SACK        5    /* selective ack (rfc1072) */
  55. #endif
  56. #ifndef TCPOPT_ECHO
  57. #define    TCPOPT_ECHO        6    /* echo (rfc1072) */
  58. #endif
  59. #ifndef TCPOPT_ECHOREPLY
  60. #define    TCPOPT_ECHOREPLY    7    /* echo (rfc1072) */
  61. #endif
  62. #ifndef TCPOPT_TIMESTAMP
  63. #define TCPOPT_TIMESTAMP    8    /* timestamps (rfc1323) */
  64. #endif
  65.  
  66. struct tha {
  67.     struct in_addr src;
  68.     struct in_addr dst;
  69.     u_int port;
  70. };
  71.  
  72. struct tcp_seq_hash {
  73.     struct tcp_seq_hash *nxt;
  74.     struct tha addr;
  75.     tcp_seq seq;
  76.     tcp_seq ack;
  77. };
  78.  
  79. #define TSEQ_HASHSIZE 919
  80.  
  81. static struct tcp_seq_hash tcp_seq_hash[TSEQ_HASHSIZE];
  82.  
  83.  
  84. void
  85. tcp_print(register const u_char *bp, register int length,
  86.       register const u_char *bp2)
  87. {
  88.     register const struct tcphdr *tp;
  89.     register const struct ip *ip;
  90.     register u_char flags;
  91.     register int hlen;
  92.     u_short sport, dport, win, urp;
  93.     u_int32 seq, ack;
  94.  
  95.     tp = (struct tcphdr *)bp;
  96.     ip = (struct ip *)bp2;
  97.     if ((const u_char *)(tp + 1)  > snapend) {
  98.         printf("[|tcp]");
  99.         return;
  100.     }
  101.     if (length < sizeof(struct tcphdr)) {
  102.         (void)printf("truncated-tcp %d", length);
  103.         return;
  104.     }
  105.  
  106.     sport = ntohs(tp->th_sport);
  107.     dport = ntohs(tp->th_dport);
  108.     seq = ntohl(tp->th_seq);
  109.     ack = ntohl(tp->th_ack);
  110.     win = ntohs(tp->th_win);
  111.     urp = ntohs(tp->th_urp);
  112.  
  113.     (void)printf("%s.%s > %s.%s: ",
  114.         ipaddr_string(&ip->ip_src), tcpport_string(sport),
  115.         ipaddr_string(&ip->ip_dst), tcpport_string(dport));
  116.  
  117.     if (qflag) {
  118.         (void)printf("tcp %d", length - tp->th_off * 4);
  119.         return;
  120.     }
  121.     if ((flags = tp->th_flags) & (TH_SYN|TH_FIN|TH_RST|TH_PUSH)) {
  122.         if (flags & TH_SYN)
  123.             putchar('S');
  124.         if (flags & TH_FIN)
  125.             putchar('F');
  126.         if (flags & TH_RST)
  127.             putchar('R');
  128.         if (flags & TH_PUSH)
  129.             putchar('P');
  130.     } else
  131.         putchar('.');
  132.  
  133.     if (!Sflag && (flags & TH_ACK)) {
  134.         register struct tcp_seq_hash *th;
  135.         register int rev;
  136.         struct tha tha;
  137.         /*
  138.          * Find (or record) the initial sequence numbers for
  139.          * this conversation.  (we pick an arbitrary
  140.          * collating order so there's only one entry for
  141.          * both directions).
  142.          */
  143.         if (sport < dport ||
  144.             (sport == dport &&
  145.              ip->ip_src.s_addr < ip->ip_dst.s_addr)) {
  146.             tha.src = ip->ip_src, tha.dst = ip->ip_dst;
  147.             tha.port = sport << 16 | dport;
  148.             rev = 0;
  149.         } else {
  150.             tha.src = ip->ip_dst, tha.dst = ip->ip_src;
  151.             tha.port = dport << 16 | sport;
  152.             rev = 1;
  153.         }
  154.  
  155.         for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
  156.              th->nxt; th = th->nxt)
  157.             if (!bcmp((char *)&tha, (char *)&th->addr,
  158.                   sizeof(th->addr)))
  159.                 break;
  160.  
  161.         if (!th->nxt || flags & TH_SYN) {
  162.             /* didn't find it or new conversation */
  163.             if (!th->nxt)
  164.                 th->nxt = (struct tcp_seq_hash *)
  165.                     calloc(1, sizeof (*th));
  166.             th->addr = tha;
  167.             if (rev)
  168.                 th->ack = seq, th->seq = ack - 1;
  169.             else
  170.                 th->seq = seq, th->ack = ack - 1;
  171.         } else {
  172.             if (rev)
  173.                 seq -= th->ack, ack -= th->seq;
  174.             else
  175.                 seq -= th->seq, ack -= th->ack;
  176.         }
  177.     }
  178.     hlen = tp->th_off * 4;
  179.     length -= hlen;
  180.     if (length > 0 || flags & (TH_SYN | TH_FIN | TH_RST))
  181.         (void)printf(" %u:%u(%d)", seq, seq + length, length);
  182.     if (flags & TH_ACK)
  183.         (void)printf(" ack %u", ack);
  184.  
  185.     (void)printf(" win %d", win);
  186.  
  187.     if (flags & TH_URG)
  188.         (void)printf(" urg %d", urp);
  189.     /*
  190.      * Handle any options.
  191.      */
  192.     if ((hlen -= sizeof(struct tcphdr)) > 0) {
  193.         register const u_char *cp = (const u_char *)tp + sizeof(*tp);
  194.         int i;
  195.         char ch = '<';
  196.  
  197.         putchar(' ');
  198.         while (--hlen >= 0) {
  199.             putchar(ch);
  200.             switch (*cp++) {
  201.             case TCPOPT_MAXSEG:
  202.             {
  203.                 (void)printf("mss %d", cp[1] << 8 | cp[2]);
  204.                 if (*cp != 4)
  205.                     (void)printf("[len %d]", *cp);
  206.                 cp += 3;
  207.                 hlen -= 3;
  208.                 break;
  209.             }
  210.             case TCPOPT_EOL:
  211.                 (void)printf("eol");
  212.                 break;
  213.             case TCPOPT_NOP:
  214.                 (void)printf("nop");
  215.                 break;
  216.             case TCPOPT_WSCALE:
  217.                 (void)printf("wscale %d", cp[1]);
  218.                 if (*cp != 3)
  219.                     (void)printf("[len %d]", *cp);
  220.                 cp += 2;
  221.                 hlen -= 2;
  222.                 break;
  223.             case TCPOPT_SACKOK:
  224.                 (void)printf("sackOK");
  225.                 if (*cp != 2)
  226.                     (void)printf("[len %d]", *cp);
  227.                 cp += 1;
  228.                 hlen -= 1;
  229.                 break;
  230.             case TCPOPT_ECHO:
  231.             {
  232.                 (void)printf("echo %u",
  233.                          cp[1] << 24 | cp[2] << 16 |
  234.                          cp[3] << 8 | cp[4]);
  235.                 if (*cp != 6)
  236.                     (void)printf("[len %d]", *cp);
  237.                 cp += 5;
  238.                 hlen -= 5;
  239.                 break;
  240.             }
  241.             case TCPOPT_ECHOREPLY:
  242.             {
  243.                 (void)printf("echoreply %u",
  244.                          cp[1] << 24 | cp[2] << 16 |
  245.                          cp[3] << 8 | cp[4]);
  246.                 if (*cp != 6)
  247.                     (void)printf("[len %d]", *cp);
  248.                 cp += 5;
  249.                 hlen -= 5;
  250.                 break;
  251.             }
  252.             case TCPOPT_TIMESTAMP:
  253.             {
  254.                 (void)printf("timestamp %lu %lu",
  255.                          cp[1] << 24 | cp[2] << 16 |
  256.                          cp[3] << 8 | cp[4],
  257.                          cp[5] << 24 | cp[6] << 16 |
  258.                          cp[7] << 8 | cp[8]);
  259.                 if (*cp != 10)
  260.                     (void)printf("[len %d]", *cp);
  261.                 cp += 9;
  262.                 hlen -= 9;
  263.                 break;
  264.               }
  265.             default:
  266.                 (void)printf("opt-%d:", cp[-1]);
  267.                 for (i = *cp++ - 2, hlen -= i + 1; i > 0; --i)
  268.                     (void)printf("%02x", *cp++);
  269.                 break;
  270.             }
  271.             ch = ',';
  272.         }
  273.         putchar('>');
  274.     }
  275. }
  276.  
  277.